home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / libs / knowhow4 / sview.cpp < prev    next >
C/C++ Source or Header  |  1994-10-10  |  13KB  |  485 lines

  1. #include "sview.h"
  2.  
  3. char* firstString(int first, char* string)
  4.     {
  5.     char* str = string;
  6.     for(int i = 0; i < first && str != NULL; i++)
  7.     {
  8.     str = strchr(str, '\n');
  9.     if(str != NULL)
  10.         str++;
  11.     }
  12.     return str;
  13.     }
  14. ///////////////////////////
  15. ScrollView::ScrollView(loc start_pos, char* str, rect b, loc sc, int interv,
  16.                int dir)
  17.     {
  18.     bnd = b;
  19.     start = loc(0, 0); pos = start_pos; string = str;
  20.     number_of_nl = nRet(string);
  21.     scale = sc; interval = interv; direction = dir;
  22.     findString = NULL;
  23.     }
  24. ///////////////////////////
  25. void ScrollView::showCursor()
  26.     {
  27.     setviewport(bnd.origin.X, bnd.origin.Y,
  28.         bnd.corner.X, bnd.corner.Y, 1);
  29.  
  30.     int sz;
  31.     int size_y = interval
  32.      * (sz = fnt->scaledtextsize("H!", scale.X, scale.Y).height())
  33.          / 10 * pos.Y;                // vertical position
  34.     int sh = (interval - 10) / 2 * sz / 10;
  35.     char* tmp = firstString(pos.Y + start.Y - 1, string); // the n-th string
  36.  
  37.     tmp += start.X;                       // visible part of tmp
  38.     int size_x;                               // HP text width, pixels
  39.  
  40.     char* tmp1 = new char[pos.X + 1];         // temporary length
  41.     strncpy(tmp1, tmp, pos.X - 1);
  42.     tmp1[pos.X - 1] = '\0';                       // 0-terminated string
  43.     size_x = fnt->scaledtextsize(tmp1, scale.X, scale.Y).width();
  44.     delete tmp1;
  45.  
  46.     moveto(size_x, size_y - sh);
  47.  
  48.     setwritemode(XOR_PUT);
  49.     setlinestyle(SOLID_LINE, 1, 1);
  50.     lineto(size_x, size_y - sh - sz);
  51.     setwritemode(COPY_PUT);
  52.     setviewport(0, 0, getmaxx(), getmaxy(), 1);
  53.     curs = loc(size_x, size_y);
  54.     }
  55. /////////////////////////
  56. int ScrollView::lineLen(int num)
  57.     {
  58.     char* str1 = firstString(num, string);
  59.     char* str2 = firstString(1, str1);
  60.     if(str2 == NULL)
  61.     return strlen(str1);
  62.     return str2 - str1;
  63. /*    char* c = new char[str2 - str1 + 1];
  64.     strncpy(c, str1, str2 - str1);
  65.     c[str2 - str1] = '\0';                       // 0-terminated string
  66.     int l = strlen(c);
  67.     delete c;
  68.     return l;
  69. */    }
  70. /////////////////////////
  71. char* ScrollView::showString(char* str, loc scale,
  72.                  int mode)
  73.     {
  74.     char* s = strchr(str, '\n');
  75.     if(s != NULL)
  76.     {
  77.     int new_pos = s - str;
  78.     char c = str[new_pos];
  79.     str[new_pos] = '\0';
  80.     if(new_pos > start.X)
  81.         drawscaledstr(*fnt, str + start.X, scale.X,
  82.           scale.Y, mode, direction);
  83.     str[new_pos] = c;
  84.     return str + new_pos + 1;
  85.     }
  86.     if(strlen(str) > start.X)
  87.     drawscaledstr(*fnt, str + start.X, scale.X,
  88.           scale.Y, mode, direction);
  89.     return NULL;
  90.     }
  91. /////////////////////////
  92. void ScrollView::show(int first, int last, int mode, int shift)
  93.     {
  94.     char* str = firstString(first - 1, string);
  95.  
  96.     setviewport(bnd.origin.X, bnd.origin.Y,
  97.         bnd.corner.X, bnd.corner.Y, 1);
  98.  
  99.     int s_size = interval
  100.          * fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
  101.  
  102.     int top = (first - start.Y - 1) * s_size;
  103.     int sh = (interval - 10) / 2
  104.          * fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
  105.     if(first != last || shift > 0)
  106.     curs.X = 0;
  107.     else
  108.     str += pos.X + shift - 1;
  109.     struct viewporttype viewinfo;
  110.     getviewsettings(&viewinfo);
  111.     if(curs.X == 0)
  112.     {
  113.     setviewport(viewinfo.left - 3, viewinfo.top,
  114.         viewinfo.right + 3, viewinfo.bottom, 1);
  115.     }
  116.     bar(curs.X, top, viewinfo.right - viewinfo.left + 7,
  117.     top + s_size * (last - first + 1));
  118.     setviewport(viewinfo.left, viewinfo.top, viewinfo.right,
  119.            viewinfo.bottom, 1);
  120.     moveto(curs.X, top - sh + s_size);
  121.  
  122.     for(int i = first; i <= last; i++)
  123.     {
  124.     if((str = showString(str, scale, mode)) == NULL)
  125.         break;
  126.     moveto(0, s_size * (i - start.Y + 1) - sh);
  127.     }
  128.     setviewport(0, 0, getmaxx(), getmaxy(), 1);
  129.     }
  130. //////////////////////////
  131. int ScrollView::up(int jmp)
  132.     {
  133.     setviewport(bnd.origin.X, bnd.origin.Y,
  134.         bnd.corner.X, bnd.corner.Y, 1);
  135.  
  136.     int ret = 1;
  137.     hideCursor();
  138.     int h = interval
  139.         * fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
  140.     int view_h = bnd.height() / h;
  141.     if(pos.Y > jmp)
  142.     {
  143.     pos.Y -= jmp;
  144.     int len;
  145.     if(len = lineLen(pos.Y + start.Y - 1) < pos.X + start.X)
  146.         {
  147.         pos.X = 1; start.X = len - 1;
  148.         show(start.Y + 1, start.Y + bnd.height() / h);
  149.         }
  150.     }
  151.     else
  152.     {
  153.     if((start.Y > jmp - 1) || (start.Y > view_h - 1))
  154.         {
  155.         if(start.Y > view_h - 1)
  156.         {
  157.         start.Y -= view_h;
  158.         pos.Y = view_h - jmp + 1;
  159.         }
  160.         else                             // if(start.Y > jmp - 1)
  161.         {
  162.         pos.Y = start.Y - jmp + 1;
  163.         start.Y = 0;
  164.         }
  165.         int len = lineLen(pos.Y + start.Y - 1);
  166.         if(len < pos.X + start.X)
  167.         {
  168.         pos.X = 1; start.X = len - 1;
  169.         }
  170.         show(start.Y + 1, start.Y + 1 + bnd.height() / h);
  171.         }
  172.     else
  173.         ret = 0;
  174.     }
  175.     showCursor();
  176.     setviewport(0, 0, getmaxx(), getmaxy(), 1);
  177.  
  178.     return ret;
  179.     }
  180. /////////////////////////////////
  181. int ScrollView::dn(int jmp)
  182.     {
  183.     setviewport(bnd.origin.X, bnd.origin.Y,
  184.         bnd.corner.X, bnd.corner.Y, 1);
  185.  
  186.     int ret = 1;
  187.     hideCursor();
  188.     int h = interval
  189.         * fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
  190.     int view_h = bnd.height() / h;
  191.  
  192.     if(pos.Y + jmp - 2 < view_h && start.Y + pos.Y + jmp - 2 < number_of_nl)
  193.     {
  194.     pos.Y += jmp;
  195.     int len = lineLen(start.Y + pos.Y - 1);
  196.     if(len < pos.X + start.X)
  197.         {
  198.         pos.X = 1; start.X = len ? len - 1 : 0;
  199.         show(start.Y + 1, start.Y + 1 + bnd.height() / h);
  200.         }
  201.     }
  202.     else
  203.     {
  204.     if((start.Y + view_h - 2 < number_of_nl)
  205.        || (start.Y + pos.Y + jmp - 2 < number_of_nl))
  206.         {
  207.         if(start.Y + view_h - 2 < number_of_nl)
  208.         {
  209.         start.Y += view_h;
  210.         pos.Y = 1;
  211.         }
  212.         else           // if(start.Y + pos.Y + jmp - 1 < number_of_nl)
  213.         {
  214.         start.Y += jmp;
  215.         }
  216.         int len;
  217.         if(len = lineLen(start.Y + pos.Y - 1) < pos.X + start.X)
  218.         {
  219.         pos.X = 1; start.X = len - 1;
  220.         }
  221.         show(start.Y + 1, start.Y + 1 + bnd.height() / h);
  222.         }
  223.     else
  224.         ret = 0;
  225.     }
  226.     showCursor();
  227.     setviewport(0, 0, getmaxx(), getmaxy(), 1);
  228.     return ret;
  229.     }
  230. /////////////////////////////////
  231. int ScrollView::left(int jmp)
  232.     {
  233.     setviewport(bnd.origin.X, bnd.origin.Y,
  234.         bnd.corner.X, bnd.corner.Y, 1);
  235.     int ret = 0;
  236.     hideCursor();
  237.  
  238.     if(pos.X > jmp)          // not leftmost position
  239.     pos.X -= jmp;
  240.     else                   // leftmost screen position
  241.     {
  242.     if(start.X > jmp - 1)
  243.         {
  244.         ret = 1;
  245.         start.X -= jmp;
  246.         int h = interval
  247.         * fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
  248.         show(start.Y + 1, start.Y + 1 + bnd.height() / h);
  249.         }
  250.     }
  251.     showCursor();
  252.     setviewport(0, 0, getmaxx(), getmaxy(), 1);
  253.     return ret;
  254.     }
  255. ////////////////////////
  256. char* ScrollView::getLine(int n)
  257.     {
  258.     char* str = firstString(n, string);
  259.     if(str == NULL)
  260.     return NULL;
  261.     char* str1;
  262.     int len = ((str1 = firstString(1, str)) == NULL) ? strlen(str)
  263.                         : str1 - str - 1;
  264.     char* c = new char[len + 5];
  265.     strncpy(c, str, len);
  266.     c[len] = '\0';                       // 0-terminated string
  267.     return c;
  268.     }
  269. /////////////////////////
  270. int ScrollView::right(int jmp)
  271.     {
  272.     setviewport(bnd.origin.X, bnd.origin.Y,
  273.         bnd.corner.X, bnd.corner.Y, 1);
  274.     int ret = 0;
  275.     hideCursor();
  276.     char* str = getLine(start.Y + pos.Y - 1);                // current line
  277.     if(start.X + pos.X + jmp - 2           // if we'll not leave this line
  278.     < lineLen(start.Y + pos.Y - 1))    // after this jump
  279.     {
  280.     str[start.X + pos.X + jmp - 1] = '\0';  // NULL-terminates line
  281.     int len = fnt->scaledtextsize(str + start.X,  // length of visible
  282.                scale.X, scale.Y).width();     // part, pixels
  283.  
  284.     if(bnd.width() > len)  // not rightmost position
  285.         pos.X += jmp;
  286.     else                   // rightmost screen position
  287.         {
  288.         ret = 1;
  289.         start.X += jmp;
  290.         while(fnt->scaledtextsize(str + start.X,
  291.                     scale.X, scale.Y).width() > bnd.width())
  292.         {
  293.         start.X++;
  294.         pos.X--;
  295.         }
  296.         int h = interval
  297.         * fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
  298.         show(start.Y + 1, start.Y + 1 + bnd.height() / h);
  299.         }
  300.     }
  301.     showCursor();
  302.     delete str;
  303.     setviewport(0, 0, getmaxx(), getmaxy(), 1);
  304.     return ret;
  305.     }
  306. ////////////////////////
  307. void ScrollView::home()
  308.     {
  309.     setviewport(bnd.origin.X, bnd.origin.Y,
  310.         bnd.corner.X, bnd.corner.Y, 1);
  311.  
  312.     hideCursor();
  313.     pos.X = 1;
  314.     if(start.X != 0)
  315.     {
  316.     start.X = 0;
  317.     int h = interval
  318.         * fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
  319.     show(start.Y + 1, start.Y + 1 + bnd.height() / h);
  320.     }
  321.     start.X = 0;
  322.     showCursor();
  323.     setviewport(0, 0, getmaxx(), getmaxy(), 1);
  324.  
  325.     }
  326. ////////////////////////
  327. void ScrollView::end()
  328.     {
  329.     setviewport(bnd.origin.X, bnd.origin.Y,
  330.         bnd.corner.X, bnd.corner.Y, 1);
  331.  
  332.     hideCursor();
  333.     pos.X = 1;
  334.     char* str = getLine(start.Y + pos.Y - 1);
  335.     start.X = strlen(str);
  336.     int h = interval
  337.         * fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
  338.     show(start.Y + 1, start.Y + 1 + bnd.height() / h);
  339.     showCursor();
  340.     delete str;
  341.     setviewport(0, 0, getmaxx(), getmaxy(), 1);
  342.  
  343.     }
  344. ////////////////////////
  345. int ScrollView::pgUp()
  346.     {
  347.     setviewport(bnd.origin.X, bnd.origin.Y,
  348.         bnd.corner.X, bnd.corner.Y, 1);
  349.     int ret = 1;
  350.     hideCursor();
  351.     int h = interval
  352.         * fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
  353.     h = bnd.height() / h;
  354.     if(h < start.Y)
  355.     {
  356.     start.Y -= h;
  357.     pos.Y = 1;
  358.     pos.X = 1;
  359.     show(start.Y + 1, start.Y + 1 + h);
  360.     }
  361.     else
  362.     ret = 0;
  363.  
  364.     showCursor();
  365.     setviewport(0, 0, getmaxx(), getmaxy(), 1);
  366.     return ret;
  367.     }
  368. /////////////////////////
  369. int ScrollView::pgDn()
  370.     {
  371.     setviewport(bnd.origin.X, bnd.origin.Y,
  372.         bnd.corner.X, bnd.corner.Y, 1);
  373.     int ret = 1;
  374.     hideCursor();
  375.     int h = interval
  376.         * fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
  377.     h = bnd.height() / h;
  378.     char* str = firstString(start.Y + pos.Y - 1, string);
  379.     int returns = nRet(str);
  380.     if(h < returns)
  381.     {
  382.     start.Y += h;
  383.     pos.X = 1;
  384.     show(start.Y + 1, start.Y + 1 + h);
  385.     }
  386.     else
  387.     ret = 0;
  388.     showCursor();
  389.     setviewport(0, 0, getmaxx(), getmaxy(), 1);
  390.     return ret;
  391.     }
  392. /////////////////////////
  393. void ScrollView::toTop()
  394.     {
  395.     setviewport(bnd.origin.X, bnd.origin.Y,
  396.         bnd.corner.X, bnd.corner.Y, 1);
  397.  
  398.     hideCursor();
  399.     int h = interval
  400.         * fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
  401.     h = bnd.height() / h;
  402.     start = loc(0, 0);
  403.     pos = loc(1, 1);
  404.     show(start.Y + 1, start.Y + 1 + h);
  405.     showCursor();
  406.     setviewport(0, 0, getmaxx(), getmaxy(), 1);
  407.  
  408.     }
  409. //////////////////////////
  410. void ScrollView::toBottom()
  411.     {
  412.     setviewport(bnd.origin.X, bnd.origin.Y,
  413.         bnd.corner.X, bnd.corner.Y, 1);
  414.  
  415.     hideCursor();
  416.     int h = interval
  417.         * fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
  418.     h = bnd.height() / h;
  419.     start = loc(0, nRet(string));
  420.     pos = loc(1, 1);
  421.     show(start.Y + 1, start.Y + h + 1);
  422.     showCursor();
  423.     setviewport(0, 0, getmaxx(), getmaxy(), 1);
  424.  
  425.     }
  426. ///////////////////////////
  427. int ScrollView::find(char* search)
  428.     {
  429.     setviewport(bnd.origin.X, bnd.origin.Y,
  430.         bnd.corner.X, bnd.corner.Y, 1);
  431.  
  432.     int ret = 0;                                     // find or not
  433.     hideCursor();
  434.     char* str = firstString(start.Y + pos.Y - 1, string);      // start search position
  435.     char* fnd = strstr(str + 1, search);                // first
  436.     if(fnd != NULL)                                 // if search string
  437.     {                                            //     presents
  438.     int h = interval
  439.         * fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
  440.     h = bnd.height() / h;                        // screen height, in HP intervals
  441.     int y_pos = nRet(string) - nRet(fnd) + 1;   // y pos of find string
  442.     if(start.Y + h >= y_pos)                     // do not redraw screen
  443.         pos.Y = y_pos - start.Y;
  444.     else                                         // redraw screen
  445.         {
  446.         start.Y = y_pos - 1;
  447.         pos.Y = 1;
  448.         }
  449.  
  450.     char* work = getLine(y_pos - 1);              // line containing str
  451.     char* work1 = firstString(y_pos - 1, string); // part of string
  452.     int x_pos = fnd - work1;           // distance from line beginning
  453.     if(x_pos <= start.X)                // redraw screen
  454.         {
  455.         start.X = x_pos;
  456.         pos.X = 1;
  457.         }
  458.     else
  459.         {
  460.         work[x_pos] = '\0';
  461.         if(fnt->scaledtextsize(work + start.X, scale.X, scale.Y).width()
  462.                        >= bnd.width())  // we are not in bnd
  463.         {
  464.         start.X = x_pos;
  465.         pos.X = 1;
  466.         }
  467.         else                                       // we are in bnd
  468.         pos.X = x_pos - start.X;
  469.         }
  470.     ret = 1;
  471.     delete work;
  472.     show(start.Y + 1, start.Y + h + 1);
  473.     }
  474.  
  475.     showCursor();
  476.     setviewport(0, 0, getmaxx(), getmaxy(), 1);
  477.  
  478.     return ret;
  479.     }
  480. /////////////////////////
  481. /*
  482.  
  483. */
  484. /////////////////////////
  485.